package com.ruoyi.system.service.impl;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;

import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.ruoyi.common.config.RuoYiConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.QualificationStudentMapper;
import com.ruoyi.system.domain.QualificationStudent;
import com.ruoyi.system.service.IQualificationStudentService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.mapper.PhysicalStudentMapper;
import com.ruoyi.system.domain.PhysicalStudent;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.client.j2se.MatrixToImageWriter;

import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;

/**
 * 警校考生资格审查信息Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-04-01
 */
@Service
public class QualificationStudentServiceImpl implements IQualificationStudentService 
{
    @Autowired
    private QualificationStudentMapper qualificationStudentMapper;

    @Autowired
    private PhysicalStudentMapper physicalStudentMapper;

    /**
     * 查询警校考生资格审查信息
     * 
     * @param id 警校考生资格审查信息主键
     * @return 警校考生资格审查信息
     */
    @Override
    public QualificationStudent selectQualificationStudentById(Long id)
    {
        return qualificationStudentMapper.selectQualificationStudentById(id);
    }

    /**
     * 查询警校考生资格审查信息列表
     * 
     * @param qualificationStudent 警校考生资格审查信息
     * @return 警校考生资格审查信息
     */
    @Override
    public List<QualificationStudent> selectQualificationStudentList(QualificationStudent qualificationStudent)
    {
        return qualificationStudentMapper.selectQualificationStudentList(qualificationStudent);
    }

    /**
     * 新增警校考生资格审查信息
     * 
     * @param qualificationStudent 警校考生资格审查信息
     * @return 结果
     */
    @Override
    public int insertQualificationStudent(QualificationStudent qualificationStudent)
    {
        return qualificationStudentMapper.insertQualificationStudent(qualificationStudent);
    }

    /**
     * 修改警校考生资格审查信息
     * 
     * @param qualificationStudent 警校考生资格审查信息
     * @return 结果
     */
    @Override
    public int updateQualificationStudent(QualificationStudent qualificationStudent)
    {
        // 更新考生资格审查信息
        int rows = qualificationStudentMapper.updateQualificationStudent(qualificationStudent);
        
        // 如果资格审查更新为"通过"，则自动将考生信息添加到体能测评
        if (rows > 0 && "通过".equals(qualificationStudent.getQualificationReview())) {
            // 查询该考生在体能测评中是否已存在
            PhysicalStudent physicalQuery = new PhysicalStudent();
            physicalQuery.setRegistrationId(qualificationStudent.getRegistrationId());
            List<PhysicalStudent> existingPhysical = physicalStudentMapper.selectPhysicalStudentList(physicalQuery);
            
            // 如果不存在，则添加
            if (existingPhysical == null || existingPhysical.isEmpty()) {
                PhysicalStudent newPhysicalStudent = new PhysicalStudent();
                // 复制必要信息
                copyStudentBaseInfo(qualificationStudent, newPhysicalStudent);
                // 设置创建者
                if (StringUtils.isNotEmpty(qualificationStudent.getUpdateBy())) {
                    newPhysicalStudent.setCreateBy(qualificationStudent.getUpdateBy());
                }
                // 插入到体能测评
                physicalStudentMapper.insertPhysicalStudent(newPhysicalStudent);
            }
        }
        
        return rows;
    }

    /**
     * 复制考生基本信息
     * 
     * @param source 源对象
     * @param target 目标对象
     */
    private void copyStudentBaseInfo(QualificationStudent source, PhysicalStudent target) {
        target.setRegistrationId(source.getRegistrationId());
        target.setName(source.getName());
        target.setIdCard(source.getIdCard());
        target.setGender(source.getGender());
        target.setNativeCity(source.getNativeCity());
        target.setWrittenExamNo(source.getWrittenExamNo());
        target.setComputerExamNo(source.getComputerExamNo());
        target.setAdministrativeScore(source.getAdministrativeScore());
        target.setEssayScore(source.getEssayScore());
        target.setProfessionalScore(source.getProfessionalScore());
        target.setTotalScore(source.getTotalScore());
        target.setCompositeScore(source.getCompositeScore());
        target.setInterviewScore(source.getInterviewScore());
        target.setAdministrativeAbsent(source.getAdministrativeAbsent());
        target.setEssayAbsent(source.getEssayAbsent());
        target.setProfessionalAbsent(source.getProfessionalAbsent());
        target.setPoliticalStatus(source.getPoliticalStatus());
        target.setHighestDegree(source.getHighestDegree());
        target.setAcademicDegree(source.getAcademicDegree());
        target.setGraduateSchool(source.getGraduateSchool());
        target.setDepartment(source.getDepartment());
        target.setMajor(source.getMajor());
        target.setPhoneNumber(source.getPhoneNumber());
        target.setQualificationReview(source.getQualificationReview());
    }

    /**
     * 批量修改警校考生资格审查结果
     * 
     * @param qualificationStudentList 包含学生ID和新资格审查结果的列表
     * @return 结果
     */
    @Override
    public int batchUpdateQualificationReview(List<QualificationStudent> qualificationStudentList)
    {
        qualificationStudentList.forEach(qualificationStudent -> {
            // 更新考生资格审查信息
            qualificationStudentMapper.updateQualificationStudent(qualificationStudent);

            // 如果资格审查更新为"通过"，则自动将考生信息添加到体能测评
            if ("通过".equals(qualificationStudent.getQualificationReview())) {
                // 查询该考生在体能测评中是否已存在
                PhysicalStudent physicalQuery = new PhysicalStudent();
                physicalQuery.setRegistrationId(qualificationStudent.getRegistrationId());
                List<PhysicalStudent> existingPhysical = physicalStudentMapper.selectPhysicalStudentList(physicalQuery);

                // 如果不存在，则添加
                if (existingPhysical == null || existingPhysical.isEmpty()) {
                    PhysicalStudent newPhysicalStudent = new PhysicalStudent();
                    // 复制必要信息
                    copyStudentBaseInfo(qualificationStudent, newPhysicalStudent);
                    // 设置创建者
                    if (StringUtils.isNotEmpty(qualificationStudent.getUpdateBy())) {
                        newPhysicalStudent.setCreateBy(qualificationStudent.getUpdateBy());
                    }
                    // 插入到体能测评
                    physicalStudentMapper.insertPhysicalStudent(newPhysicalStudent);
                }
            }
        });

        return 1;
    }

    /**
     * 批量删除警校考生资格审查信息
     * 
     * @param ids 需要删除的警校考生资格审查信息主键
     * @return 结果
     */
    @Override
    public int deleteQualificationStudentByIds(Long[] ids)
    {
        return qualificationStudentMapper.deleteQualificationStudentByIds(ids);
    }

    /**
     * 删除警校考生资格审查信息信息
     * 
     * @param id 警校考生资格审查信息主键
     * @return 结果
     */
    @Override
    public int deleteQualificationStudentById(Long id)
    {
        return qualificationStudentMapper.deleteQualificationStudentById(id);
    }
    
    /**
     * 导入警校考生资格审查信息
     * 
     * @param qualificationStudentList 警校考生资格审查信息列表
     * @param updateSupport 是否更新支持，如果已存在，是否更新数据
     * @param operName 操作用户
     * @return 结果
     */
    @Override
    public String importQualificationStudent(List<QualificationStudent> qualificationStudentList, boolean updateSupport, String operName)
    {
        if (StringUtils.isNull(qualificationStudentList) || qualificationStudentList.size() == 0)
        {
            throw new ServiceException("导入数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (QualificationStudent qualificationStudent : qualificationStudentList)
        {
            try
            {
                // 生成条形码
                String barcodePath = generateBarcode(qualificationStudent.getIdCard());

                // 验证是否存在这个学生
                QualificationStudent existingStudent = new QualificationStudent();
                if (StringUtils.isNotEmpty(qualificationStudent.getIdCard())) {
                    existingStudent.setIdCard(qualificationStudent.getIdCard());
                } else if (StringUtils.isNotEmpty(qualificationStudent.getRegistrationId())) {
                    existingStudent.setRegistrationId(qualificationStudent.getRegistrationId());
                } else {
                    failureNum++;
                    failureMsg.append("<br/>第 " + failureNum + " 条数据导入失败：身份证号和报名序号不能同时为空");
                    continue;
                }
                
                List<QualificationStudent> students = selectQualificationStudentList(existingStudent);
                
                if (students != null && students.size() > 0 && updateSupport)
                {
                    qualificationStudent.setId(students.get(0).getId());
                    qualificationStudent.setUpdateBy(operName);
                    updateQualificationStudent(qualificationStudent);
                    successNum++;
                    successMsg.append("<br/>第 " + successNum + " 条数据更新成功");
                    
                    // 如果资格审查为"通过"，则自动流转到体能测评
                    if ("通过".equals(qualificationStudent.getQualificationReview())) {
                        successMsg.append("，并已自动流转到体能测评模块");
                    }
                }
                else if (students != null && students.size() > 0 && !updateSupport)
                {
                    failureNum++;
                    failureMsg.append("<br/>第 " + failureNum + " 条数据已存在：" + qualificationStudent.getName());
                }
                else
                {
                    qualificationStudent.setCreateBy(operName);
                    insertQualificationStudent(qualificationStudent);
                    successNum++;
                    successMsg.append("<br/>第 " + successNum + " 条数据导入成功");
                    
                    // 如果资格审查为"通过"，则自动流转到体能测评
                    if ("通过".equals(qualificationStudent.getQualificationReview())) {
                        successMsg.append("，并已自动流转到体能测评模块");
                    }
                }
            }
            catch (Exception e)
            {
                failureNum++;
                String msg = "<br/>第 " + failureNum + " 条数据导入失败：";
                failureMsg.append(msg + e.getMessage());
            }
        }
        if (failureNum > 0)
        {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        }
        else
        {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    private String generateBarcode(String idCard) throws WriterException, IOException {
        String filePath = RuoYiConfig.getProfile()+"/barcode/" + idCard + ".png";
        String charset = "UTF-8"; 
        Map<EncodeHintType, ErrorCorrectionLevel> hintMap = new HashMap<>();
        hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
        BitMatrix matrix = new MultiFormatWriter().encode(new String(idCard.getBytes(charset), charset),
                BarcodeFormat.CODE_128, 200, 100, hintMap);
        Path path = FileSystems.getDefault().getPath(filePath);
        MatrixToImageWriter.writeToPath(matrix, "png", path);
        return filePath;
    }
}
